import concurrent
import json
import os
import shutil
import re
from fastapi import Depends, Request, APIRouter
from datetime import datetime
from Model.user.User import *
from Model.default import SessionLocal
from concurrent.futures import ThreadPoolExecutor
from passlib.context import CryptContext
from Model.lifedata.request.lifedata import FixLifedata_params, FixLifedata_params_Request
from api.middleware import judge_token
from config.user import VIDEO_SAVE_PATH, ALLOW_VIDEO_EXTENSIONS, IMAGE_SAVE_PATH, LIFE_KIND_DEAL_, LIFE_KIND_DEAL, \
    SEND_DIR, WEEKDAY_, SPAN_SELECT, LIFEDATA_REQUEST_LENGTH
from func.date import  are_in_same_week
from sqlalchemy import text
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# 这是个哈希加密
lifedata=APIRouter(prefix="/life_data",tags=["life_data"],dependencies=[Depends(judge_token)])
# oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/index/token")
# =======================================user-account==========================================
# 用户数据模型

#         1正常/数据 0出错   3空数据
# ========================================life_data==========================================================
# 实际应该用分布式
# 处理上传文件
# 文件可处理到云桶里
def up_load_file(save_path,file):
    session = SessionLocal()
    try:
        file_name = os.path.basename(file.filename)
        # 实际上在前一步就可以处理了，这里只为方便管理。
        if os.path.basename(file.filename).rsplit('.', 1)[1] in ALLOW_VIDEO_EXTENSIONS:
            resource_= video_info(src = VIDEO_SAVE_PATH+'/'+file_name)

        else:
            resource_ = image_info(src=IMAGE_SAVE_PATH+'/'+file_name)

        session.add(resource_)
        session.commit()
        session.flush()

        os.makedirs(save_path, exist_ok=True)
        file_path = os.path.join(save_path, file_name)
        # 将文件内容写入到本地文件
        with open(file_path, 'wb') as buffer:
            shutil.copyfileobj(file.file, buffer)
    except Exception as e:
        print(e)
        session.rollback()
        session.close()

# 删除文件
def del_load_file(file_path):
    # 检查文件是否存在
    if os.path.exists(file_path):
        os.remove(file_path)
        print(f"文件 {file_path} 已删除")
    else:
        print(f"文件 {file_path} 不存在")


# 处理life-count
def del_get_life_data_count(kind,user_id):
    session = SessionLocal()
    data = 0
    try:
        update_stmt = text(f"SELECT {kind} FROM user_behavior WHERE user_id = :user_id")
        data = int(session.execute(update_stmt, {'user_id': user_id}).first()[0])
        session.commit()
    except Exception as e:
        print(e)
    finally:
        session.close()
    return data
def deal_life_data_count(kind,user_id,count):
    session = SessionLocal()
    table='user_behavior'
    try:
        update_stmt = text(f"UPDATE {table} SET {kind} = {count} WHERE user_id = :user_id")
        session.execute(update_stmt, {'user_id': user_id})
        session.commit()
    except:
        pass
    finally:
        session.close()
def deal_life_Data_count(User_id,kind):
    session=SessionLocal()
    user_id=int(User_id)
    try:
        last=session.query(user_time_behavior).filter_by(user_id=user_id).first()
        current=int(datetime.today().timestamp())
        if are_in_same_week(int(last.last_login),current):
               deal_life_data_count(LIFE_KIND_DEAL_.get(kind),user_id,
                                int(del_get_life_data_count(LIFE_KIND_DEAL_.get(kind),user_id))+1)
        else:
            for i in LIFE_KIND_DEAL:
               deal_life_data_count(i, user_id,0)
            deal_life_data_count(LIFE_KIND_DEAL_.get(kind), user_id,1)
    except :
        pass
    finally:
        session.close()

# 上传life_data
@lifedata.post('/blog/life_data')
async def up_mylife_data(Re:Request):
    """
    用于上传生活内容
    :param Re: 注入的请求对象
    :return: 1/0
    """
    result=await  Re.form()
    title=result.get('title')
    kind=result.get('kind')
    date=result.get('date')
    content=result.get('content')
    user_id=result.get('user_id')
    thread=[]
    with ThreadPoolExecutor(max_workers=6) as executer:
        try:
            session = SessionLocal()
            # 这里必须要用这个id
            Life_data_id= session.query(static_data).filter_by(id=1).with_for_update().first()
            life_data_id=Life_data_id.life_data_id
            Life_data_id.life_data_id=life_data_id+1
            session.commit()
            session.flush()

            Life_data=life_data()
            Life_data.title=title
            Life_data.kind=kind
            Life_data.text=content
            Life_data.date=date
            Life_data.user_id=user_id
            Life_data.life_id=life_data_id

            video_src=''
            image_src=''
            for i in range(0,6):
                index='file'+str(i)
                pre_file=result.get(index)
                if (pre_file != None):
                    file_name=os.path.basename(pre_file.filename)
                    # life_data的src的分割符号
                    # save_path实际是指文件目录
                    if (os.path.basename(pre_file.filename).rsplit('.', 1)[1] in ALLOW_VIDEO_EXTENSIONS):
                        save_path = VIDEO_SAVE_PATH
                        src = f'{SEND_DIR}/{file_name}?type=video'
                        video_src+=src+',_,'
                    else:
                        save_path =IMAGE_SAVE_PATH
                        src = f'{SEND_DIR}/{file_name}?type=image'
                        image_src+=src+',_,'
                    thread.append(executer.submit(up_load_file,save_path,pre_file))


                    pass
            for i in concurrent.futures.as_completed(thread):
                 # print(i.result)
                #  有待考虑优化
                pass
            Life_data.video_info=video_src
            Life_data.image_info=image_src
            user_=session.query(user).filter_by(id=user_id).with_for_update().first()
            user_.life=user_.life+str(life_data_id)+'_+_'  #用户life_data分割符号
            session.add(Life_data)
            session.commit()
            deal_life_Data_count(user_id, kind)

        except Exception as e:
            session.rollback()
            session.close()
            return 0
    session.close()
    return  1



# 获取lifedata
# 实际这里应该加密如账户权证等
@lifedata.get('/blog/life_data/get_data')
def get_life_data(user_id :int,type:int,select:int=0):
    """
    用户用户获取所有生活数据
    :param user_id: 用户ID
    :return: []:
            data={  'life_data_id':i.life_id,
                        "title" :i.title,
                        "text" :i.text,
                        "date" :i.date,
                        "kind":i.kind,
                        "video_info":video_info_,
                       "image_info":image_info_,
                        "head_image":user_.head_image,
                        "introduction":user_.introduction
                }
    """
    Data = []
    session=SessionLocal()
    user_= session.query(user).filter_by(id=user_id).with_for_update().first()
    try:
        if user_.life :
            if select:
                # # life_id=re.split('_\+_',user_.life)
                # for i in life_id:
                #     session.query(life_data).filter_by(id=i).with_for_update().first()
                predata=session.query(life_data).filter_by(user_id=user_.id).offset((select - 1) * LIFEDATA_REQUEST_LENGTH).limit(
                        LIFEDATA_REQUEST_LENGTH).all()
            else:
                predata=session.query(life_data).filter_by(user_id=user_.id).all()

            for i in predata:
                    if i.able==type:
                        video_info_ = []
                        image_info_ = []
                        if i.video_info:
                            for j in re.split(',_,',i.video_info):
                                if len(j) != 0:
                                     video_info_.append(j)
                        if i.image_info:
                            for j in re.split(',_,',i.image_info):
                                if len(j)!=0:
                                    image_info_.append(j)

                        data={  'life_data_id':i.life_id,
                                    "title" :i.title,
                                    "text" :i.text,
                                    "date" :i.date,
                                    "kind":i.kind,
                                    "video_info":video_info_,
                                    "image_info":image_info_,
                                    "head_image":user_.head_image,
                                    "introduction":user_.introduction
                                }
                        Data.append(data)

            return Data
        else:
            return  3
    except Exception as e:
        print(e)
        pass
    finally:
        session.close()


@lifedata.get("/blog/life_data/get_data/byID")
def get_life_data_part_byid(id:str,user_id:str):
    """
    直接根据生活记录id,用户id 获取数据
    :param id: 记录ID
    :param user_id: 用户ID
    :return:  data = {'life_data_id': pre_Data.life_id,
                "title": pre_Data.title,
                "text": pre_Data.text,
                "date": pre_Data.date,
                "kind": pre_Data.kind,
                "video_info": video_info_,
                "image_info": image_info_,
                "able": pre_Data.able
                }
    """
    session=SessionLocal()
    video_info_=[]
    image_info_=[]
    try:
        pre_Data=session.query(life_data).filter_by(user_id=user_id, life_id=id).first()
        if pre_Data.video_info:
            for j in re.split(',_,', pre_Data.video_info):
                    if len(j) != 0:
                        video_info_.append(j)
        if pre_Data.image_info:
            for j in re.split(',_,', pre_Data.image_info):
                    if len(j)!=0:
                        image_info_.append(j)
        data = {'life_data_id': pre_Data.life_id,
                "title": pre_Data.title,
                "text": pre_Data.text,
                "date": pre_Data.date,
                "kind": pre_Data.kind,
                "video_info": video_info_,
                "image_info": image_info_,
                "able": pre_Data.able
                }
        return data
    except:
        return  0
        pass
    finally:
        session.close()


# 分开获取各种life_Data方便管理平台
@lifedata.get('/blog/life_data/get_data/{kind}')
def get_life_data_part(kind:str,user_id:int,select:int=0):
    """
    根据生活记录类型获取数据
    :param kind: 类型
    :param user_id: 用户ID
    :return: []:  data={  'life_data_id':i.life_id,
                "title" :i.title,
                "text" :i.text,
                "date" :i.date,
                "kind":i.kind,
                "video_info":video_info_,
                "image_info":image_info_,
                "head_image":user_.head_image,
                "introduction":user_.introduction,
                "able":i.able
                }
    """
    try:
        session=SessionLocal()
        user_=session.query(user).filter_by(id=user_id).with_for_update().first()
        session.commit()
        session.flush()
        Data=[]
        video_info_=[]
        image_info_=[]
        if select:
            pre_data = (session.query(life_data).filter_by(user_id=user_.id, kind=kind)
                        .offset((select - 1) * LIFEDATA_REQUEST_LENGTH).limit(LIFEDATA_REQUEST_LENGTH).all())
        else:
            pre_data=session.query(life_data).filter_by(user_id=user_.id, kind=kind).all()
        session.commit()
        for i in pre_data:
            if i.video_info:
                for j in re.split(',_,', i.video_info):
                    if len(j) != 0:
                        video_info_.append(j)
            if i.image_info:
                for j in re.split(',_,', i.image_info):
                    if len(j) != 0:
                        image_info_.append(j)
            data={  'life_data_id':i.life_id,
                    "title" :i.title,
                    "text" :i.text,
                    "date" :i.date,
                    "kind":i.kind,
                    "video_info":video_info_,
                    "image_info":image_info_,
                    "head_image":user_.head_image,
                    "introduction":user_.introduction,
                    "able":i.able
                    }
            Data.append(data)
        return Data
    except Exception as e:
        session.rollback()
    finally:
        session.close()



# 修改lif_data的状态


@lifedata.post("/blog/life_data/fix_data")
def del_life_data( fix_params: FixLifedata_params = Depends(FixLifedata_params),
    fix_params_request: FixLifedata_params_Request = Depends(FixLifedata_params_Request),):
    """
    生活记录状态修改
    采取假删除形式
    根据类型处理
    :param user_id: 用户ID
    :param id: 记录ID
    :param kind: 类型.
    :return: 1/0
    """
    session=SessionLocal()
    kind=fix_params.kind
    user_id=fix_params.user_id
    id=fix_params.id
    print(fix_params)
    try:
        #状态  1可用，2回收状态，0删除 ,
        #4,批量回收
        if kind==2:
            # session.query(life_data).filter_by(user_id=user_id,life_id=id).delete()
            result=session.query(life_data).filter_by(user_id=user_id, life_id=id).first()
            if result:
                result.able=2
                session.commit()
                return 1
        if kind ==0:
            result = session.query(life_data).filter_by(user_id=user_id, life_id=id).first()
            if result:
                result.able=0
                session.commit()
                return 1
        if kind ==1:
            result = session.query(life_data).filter_by(user_id=user_id, life_id=id).first()
            if result:
                result.able=1
                session.commit()
                return 1
        if kind ==4:
            # 减少前端处理流程。在后端处理
            pre_id=fix_params_request.id_list
            for i in pre_id:

                result=session.query(life_data).filter_by(user_id=user_id, life_id=i).first()

                if result:
                    result.able=2

            session.commit()
            return 1
            pass


    except:
        session.rollback()
        session.close()
        return 0
    finally:
        session.close()






# 获取用户登录数据分析
@lifedata.get("/blog/life_data/get_data/anaysis/time_long")
def get_time_long(user_id:int):
    """
    获取各项用户的登录时长分析，此处只能获取
    :param user_id: 用户ID
    :return: []:
        pre_data = {"logout": 0, "long": 0}
    """
    session=SessionLocal()
    Data=[]
    try:
        user_behavior = session.query(user_time_behavior).filter_by(user_id=user_id).first()
        user_behavior_data = {key: value for key, value in vars(user_behavior).items() if not key.startswith('_')}  # 每个字段数据
        for i in WEEKDAY_:
            if user_behavior_data.get(i) is not None:
                pre_data=json.loads(user_behavior_data.get(i))
            else:
                pre_data = {"logout": 0, "long": 0}
            Data.append(pre_data)
    except:
        pass
    finally:
        session.close()
    return Data
@lifedata.get("/blog/life_data/get_data/anaysis/time_span")
def get_time_span(user_id:int):
    session = SessionLocal()
    Data = []
    try:
        time_span=session.query(time_active_span).filter_by(user_id=user_id).first()
        user_span_data = {key: value for key, value in vars(time_span).items() if not key.startswith('_')}  # 每个字段数据
        for i in SPAN_SELECT:
            Data.append(user_span_data.get(i))
    except Exception as e:
        print(e)
        pass
    finally:
        session.close()
    return Data

@lifedata.get("/blog/life_data/get_data/anaysis/life_data_c")
def deal_get_life_cont(user_id:int):
    session=SessionLocal()
    try:
        user_=session.query(user_time_behavior).filter_by(user_id=user_id).first()
        data={
            'default':user_.k_default,
            'life':user_.k_life,
            'diary':user_.k_diary,
            'food':user_.k_food
        }
        return  data
    except:
        pass
    finally:
        session.close()




# def deal_user_habiat_pre_data(user_id:int):
#     session=SessionLocal()
#     mon_l = 0
#     tue_l = 0
#     wed_l = 0
#     thu_l = 0
#     fri_l = 0
#     sat_l = 0
#     sun_l = 0
#
#     try:
#         timebehavior=session.query(user_time_behavior).filter_by(user_id=user_id).first()#json
#         if timebehavior.mon:
#             mon_l=json.loads(timebehavior.mon)['long']
#         else:
#             mon_l=0
#         if timebehavior.tue:
#             tue_l=json.loads(timebehavior.tue)['long']
#         else:
#             tue_l=0
#         if timebehavior.wed:
#             wed_l=json.loads(timebehavior.wed)['long']
#         else:
#             wed_l=0
#         if timebehavior.thu:
#             thu_l=json.loads(timebehavior.thu)['long']
#         else:
#             thu_l=0
#         if timebehavior.fri:
#             fri_l=json.loads(timebehavior.fri)['long']
#         else:
#             fri_l=0
#         if timebehavior.sat:
#             sat_l=json.loads(timebehavior.sat)['long']
#         else:
#             sat_l=0
#         if timebehavior.sun:
#             sun_l=json.loads(timebehavior.sun)['long']
#         else:
#             sun_l=0
#
#         timespan=session.query(time_active_span).filter_by(user_id=user_id).first() #int
#         fn1_c=timespan.fn1
#         fn2_c=timespan.fn2
#         fn3_c=timespan.fn3
#         fn4_c=timespan.fn4
#         fn5_c=timespan.fn5
#         return  {
#             'long':{
#                 'mon_l':mon_l,
#                 'tue_l':tue_l,
#                 'wed_l':wed_l,
#                 'thu_l':thu_l,
#                 'fri_l':fri_l,
#                 'sat_l':sat_l,
#                 'sun_l':sun_l
#             },
#             'count':{
#                 'fn1_c':fn1_c,
#                 'fn2_c':fn2_c,
#                 'fn3_c':fn3_c,
#                 'fn4_c':fn4_c,
#                 'fn5_c':fn5_c
#             }
#         }
#     except:
#         pass
#     finally:
#         session.close()
#
#
#
#     pass


